home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-19
/
iritsm3s.zip
/
XGLGRAPH.C
< prev
Wrap
C/C++ Source or Header
|
1992-01-30
|
24KB
|
722 lines
/*****************************************************************************
* General routines to handle the graphic calls. *
* currently supported devices: *
* Input: Keyboard, mouse. *
* Output: SGI 4D using gl library device. *
* *
* Note no transformation is using the hardware. All transformation is *
* performed in xviewobj module in software. *
* *
* Written by: Gershon Elber Ver 0.1, Jul 1990. *
*****************************************************************************/
#include <gl/gl.h>
#include <gl/device.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include "irit_sm.h"
#include "genmat.h"
#include "graphgen.h"
/* Interactive menu setup structure: */
#define INTERACT_NUM_OF_STRINGS 3
#define INTERACT_NUM_OF_SUB_WNDWS_FULL 17
#define INTERACT_NUM_OF_SUB_WNDWS_PART 14
typedef struct InteractString {
RealType X, Y;
int Color;
char *Str;
} InteractString;
typedef struct InteractSubWindow {
RealType X, Y; /* Center points. */
int Color;
GraphicEventType Event;
int TextInside; /* If TRUE, Str will be in window, otherwise left to it. */
char *Str;
} InteractSubWindow;
typedef struct InteractWindowStruct { /* The interactive menu structures. */
/* Rotate, Translate, Scale strings: */
InteractString Strings[INTERACT_NUM_OF_STRINGS];
InteractSubWindow SubWindows[INTERACT_NUM_OF_SUB_WNDWS_FULL];
} InteractWindowStruct;
#define INTERACT_SUB_WINDOW_WIDTH 0.8 /* Relative to window size. */
#define INTERACT_SUB_WINDOW_HEIGHT 0.04
static int
InteractNumOfSubWndws = INTERACT_NUM_OF_SUB_WNDWS_FULL,
PopTransWndwAlways = TRUE,
TransWindowDisplayed = FALSE,
DoDoubleBuffer = TRUE;
/* Interactive mode menu set up structure is define below: */
static InteractWindowStruct InteractMenuFull = {
{ { 0.5, 0.81, RED, "Rotate" },
{ 0.5, 0.65, GREEN, "Translate" },
{ 0.5, 0.49, CYAN, "Scale" },
},
{ { 0.5, 0.93, YELLOW, EVENT_SCR_OBJ_TGL, TRUE, "Screen Coords." },
{ 0.5, 0.87, BLUE, EVENT_PERS_ORTHO_TGL,TRUE, "Perspective" },
{ 0.5, 0.83, BLUE, EVENT_PERS_ORTHO_Z, FALSE, "Z" },
{ 0.5, 0.75, RED, EVENT_ROTATE_X, FALSE, "X" }, /* Rot */
{ 0.5, 0.71, RED, EVENT_ROTATE_Y, FALSE, "Y" },
{ 0.5, 0.67, RED, EVENT_ROTATE_Z, FALSE, "Z" },
{ 0.5, 0.59, GREEN, EVENT_TRANSLATE_X, FALSE, "X" }, /* Trans */
{ 0.5, 0.55, GREEN, EVENT_TRANSLATE_Y, FALSE, "Y" },
{ 0.5, 0.51, GREEN, EVENT_TRANSLATE_Z, FALSE, "Z" },
{ 0.5, 0.43, CYAN, EVENT_SCALE, FALSE, "" }, /* Scale */
{ 0.5, 0.35, MAGENTA,EVENT_DEPTH_CUE, TRUE, "Depth cue" },
{ 0.5, 0.31, MAGENTA,EVENT_DRAW_SOLID, TRUE, "Wireframe" },
{ 0.5, 0.25, YELLOW, EVENT_SAVE_GIF, TRUE, "Save GIF" },
{ 0.5, 0.21, YELLOW, EVENT_SAVE_PS, TRUE, "Save PS" },
{ 0.5, 0.15, YELLOW, EVENT_SAVE_MATRIX, TRUE, "Save Matrix" },
{ 0.5, 0.11, YELLOW, EVENT_RESET_MATRIX, TRUE, "Reset Matrix" },
{ 0.5, 0.03, WHITE, EVENT_QUIT, TRUE, "Quit" },
}
};
static InteractWindowStruct InteractMenuPartial = {
{ { 0.5, 0.77, RED, "Rotate" },
{ 0.5, 0.59, GREEN, "Translate" },
{ 0.5, 0.41, CYAN, "Scale" },
},
{ { 0.5, 0.92, YELLOW, EVENT_SCR_OBJ_TGL, TRUE, "Screen Coords." },
{ 0.5, 0.85, BLUE, EVENT_PERS_ORTHO_TGL,TRUE, "Perspective" },
{ 0.5, 0.81, BLUE, EVENT_PERS_ORTHO_Z, FALSE, "Z" },
{ 0.5, 0.71, RED, EVENT_ROTATE_X, FALSE, "X" }, /* Rot */
{ 0.5, 0.67, RED, EVENT_ROTATE_Y, FALSE, "Y" },
{ 0.5, 0.63, RED, EVENT_ROTATE_Z, FALSE, "Z" },
{ 0.5, 0.53, GREEN, EVENT_TRANSLATE_X, FALSE, "X" }, /* Trans */
{ 0.5, 0.49, GREEN, EVENT_TRANSLATE_Y, FALSE, "Y" },
{ 0.5, 0.45, GREEN, EVENT_TRANSLATE_Z, FALSE, "Z" },
{ 0.5, 0.35, CYAN, EVENT_SCALE, FALSE, "" }, /* Scale */
{ 0.5, 0.27, MAGENTA,EVENT_DEPTH_CUE, TRUE, "Depth cue" },
{ 0.5, 0.19, MAGENTA,EVENT_DRAW_SOLID, TRUE, "Wireframe" },
{ 0.5, 0.11, YELLOW, EVENT_RESET_MATRIX, TRUE, "Reset Matrix" },
{ 0.5, 0.03, WHITE, EVENT_QUIT, TRUE, "Quit" },
}
};
static InteractWindowStruct *InteractMenu = &InteractMenuFull;
static short Colors[MAX_COLOR + 1][3] =
{
{ 0, 0, 0 }, /* 0. BLACK */
{ 0, 0, 170 }, /* 1. BLUE */
{ 0, 170, 0 }, /* 2. GREEN */
{ 0, 170, 170 }, /* 3. CYAN */
{ 170, 0, 0 }, /* 4. RED */
{ 170, 0, 170 }, /* 5. MAGENTA */
{ 170, 170, 0 }, /* 6. BROWN */
{ 170, 170, 170 }, /* 7. LIGHTGREY */
{ 85, 85, 85 }, /* 8. DARKGRAY */
{ 85, 85, 255 }, /* 9. LIGHTBLUE */
{ 85, 255, 85 }, /* 10. LIGHTGREEN */
{ 85, 255, 255 }, /* 11. LIGHTCYAN */
{ 255, 85, 85 }, /* 12. LIGHTRED */
{ 255, 85, 255 }, /* 13. LIGHTMAGENTA */
{ 255, 255, 85 }, /* 14. YELLOW */
{ 255, 255, 255 } /* 15. WHITE */
};
static long
TransWinID = 0,
TransWinWidth = 100,
TransWinWidth2 = 50,
TransWinHeight = 100,
TransWinLow = 0,
TransWinLeft = 0,
ViewWinID = 0,
ViewWinWidth = 100,
ViewWinWidth2 = 50,
ViewWinHeight = 100,
ViewWinHeight2 = 50,
ViewWinLow = 0,
ViewWinLeft = 0;
static int
InGraphicMode = FALSE;
static Matrix
ViewStartMatrix;
static long GGMapX(RealType x);
static long GGMapY(RealType y);
static void SetTransformWindow(void);
static void RedrawTransformWindow(void);
static void SetViewWindow(void);
static void DrawText(char *Str, long PosX, long PosY);
/****************************************************************************
* Routine to map real -1..1 normalized coordinates to screen X size. *
****************************************************************************/
static long GGMapX(RealType x)
{
return ViewWinWidth2 + ((long) (x * ViewWinWidth2));
}
/****************************************************************************
* Routine to map real -1..1 normalized coordinates to screen Y size. *
****************************************************************************/
static long GGMapY(RealType y)
{
return ViewWinHeight2 + ((long) (y * ViewWinHeight2));
}
/****************************************************************************
* Routine to move to a normalized point between -1..1 on both axes : *
****************************************************************************/
void GGMyMove(RealType x, RealType y)
{
move2i(GGMapX(x), GGMapY(y));
}
/****************************************************************************
* Routine to draw to a normalized point between -1..1 on both axes : *
****************************************************************************/
void GGMyDraw(RealType x, RealType y)
{
draw2i(GGMapX(x), GGMapY(y));
}
/****************************************************************************
* Routine to draw a polygon full. *
* Polygon is started by NewPoly = TRUE and Vertex == NULL, Normal == NULL. *
* Polygon is terminated NewPoly = FALSE and Vertex == NULL, Normal == NULL. *
****************************************************************************/
void GGMyDrawPolygonSolid(double *Vertex, float *Normal, int NewPoly)
{
if (Vertex == NULL && Normal == NULL) {
if (NewPoly)
bgnpolygon();
else
endpolygon();
}
else {
n3f(Normal);
v3d(Vertex);
}
}
/****************************************************************************
* Routine to set line style. *
****************************************************************************/
void GGMySetLineStyle(int Style)
{
setlinestyle((short) Style);
}
/****************************************************************************
* Routine to draw to a normelized point between -1..1 on both axes : *
****************************************************************************/
void GGMySetColor(int c)
{
static float
Ambient = 0.25,
Diffuse = 0.75,
Specular = 1.0;
static float Material[] = {
AMBIENT, 0.25, 0.25, 0.25,
DIFFUSE, 0.75, 0.75, 0.75,
SPECULAR, 1.00, 1.00, 1.00,
SHININESS, 50,
LMNULL
};
static float Light1[] = {
AMBIENT, 0.25, 0.25, 0.25,
POSITION, 0.0, 0.0, 1.0, 0.0,
LMNULL
};
static float Light2[] = {
AMBIENT, 0.25, 0.25, 0.25,
POSITION, 0.0, 0.0, -1.0, 0.0,
LMNULL
};
int i;
if (c < 0 || c > MAX_COLOR) c = WHITE;
RGBcolor(Colors[c][0], Colors[c][1], Colors[c][2]);
/* Prepare matrial structure in this color and select it. */
for (i = 0; i < 3; i++) {
Material[1 + i] = Ambient * Colors[c][i] / 255.0;
Material[5 + i] = Diffuse * Colors[c][i] / 255.0;
Material[9 + i] = Specular * Colors[c][i] / 255.0;
}
lmdef(DEFMATERIAL, 1, sizeof(Material) / sizeof(float), Material);
lmbind(MATERIAL, 1);
lmdef(DEFLIGHT, 1, sizeof(Light1) / sizeof(float), Light1);
lmbind(LIGHT1, 1);
lmdef(DEFLIGHT, 2, sizeof(Light2) / sizeof(float), Light2);
lmbind(LIGHT2, 2);
}
/****************************************************************************
* Routine to reset all the system to starting condition : *
****************************************************************************/
void GGInitGraph(int argc, char **argv, int FullTransMode, int TransAlways)
{
int i;
if (InGraphicMode) return;
if (FullTransMode) {
InteractNumOfSubWndws = INTERACT_NUM_OF_SUB_WNDWS_FULL;
InteractMenu = &InteractMenuFull;
DoDoubleBuffer = TRUE;
}
else {
InteractNumOfSubWndws = INTERACT_NUM_OF_SUB_WNDWS_PART;
InteractMenu = &InteractMenuPartial;
DoDoubleBuffer = FALSE;
}
PopTransWndwAlways = TransAlways;
SetViewWindow();
qdevice(LEFTMOUSE);
qdevice(MIDDLEMOUSE);
qdevice(RIGHTMOUSE);
/* The default drawing window is the view window. */
winset(ViewWinID);
deflinestyle((short) DOTTED_LINE, (Linestyle) 0x3333);
setbell(1); /* Make it short. */
InGraphicMode = TRUE;
}
/****************************************************************************
* Routine to close and shutdown graphic mode : *
****************************************************************************/
void GGCloseGraph(void)
{
if (!InGraphicMode) return;
InGraphicMode = FALSE;
}
/*****************************************************************************
* Routine to print a message on the given location: *
*****************************************************************************/
void GGPutMsgXY(char *s, RealType x, RealType y)
{
int Width = strwidth(s);
move2s((short) (GGMapX(x) - Width / 2),
(short) (GGMapY(y) - getheight() / 2));
charstr(s);
}
/*****************************************************************************
* Routine to clear the viewing area. *
*****************************************************************************/
void GGClearViewArea(void)
{
static Matrix
IDMat = { 1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 };
GGMySetColor(BLACK);
clear();
if (winget() == ViewWinID) {
/* activate zbuffer only if we are in solid drawing mode. */
if (GlblDrawSolid) {
mmode(MVIEWING);
ortho(-1.0, 1.0, -1.0, 1.0, -2.0, 2.0);
loadmatrix(IDMat);
/* Define necessary staff for Lighting. */
lmbind(MATERIAL, 1);
lmbind(LIGHT1, 1);
lmbind(LIGHT2, 2);
lmbind(LMODEL, 1);
zbuffer(TRUE);
zclear();
}
else {
mmode(MSINGLE);
loadmatrix(ViewStartMatrix);
zbuffer(FALSE);
}
}
}
/*****************************************************************************
* Routine to make some sound with given Frequency, Time milliseconds: *
*****************************************************************************/
void GGTone(int Frequency, int Duration)
{
if (GlblDoGraphics)
ringbell();
}
/*****************************************************************************
* Set up and draw a transformation window. *
*****************************************************************************/
static void SetTransformWindow(void)
{
long PrefPos[4];
#ifndef _AIX
foreground();
#endif
if (sscanf(GlblTransPrefPos, "%ld, %ld, %ld, %ld",
&PrefPos[0], &PrefPos[1], &PrefPos[2], &PrefPos[3]) == 4)
prefposition(PrefPos[0], PrefPos[1], PrefPos[2], PrefPos[3]);
else if (sscanf(GlblTransPrefPos, "%ld, %ld",
&PrefPos[0], &PrefPos[1]) == 2)
prefsize(PrefPos[0], PrefPos[1]);
winopen("Poly3dTrans");
if (DoDoubleBuffer) doublebuffer();
RGBmode();
gconfig();
getorigin(&TransWinLeft, &TransWinLow);
getsize(&TransWinWidth, &TransWinHeight);
TransWinWidth2 = TransWinWidth / 2;
TransWinID = winget();
GGMySetColor(BLACK);
clear();
if (DoDoubleBuffer) swapbuffers();
/* This is wierd. without the sleep the gl get mixed up between the two */
/* windows. If you have any idea why, let me know... */
sleep(1);
}
/*****************************************************************************
* Set up and draw a transformation window. *
*****************************************************************************/
static void RedrawTransformWindow(void)
{
int i;
long SubTransPosX, SubTransPosY, SubTransWidth, SubTransHeight;
/* Make sure the menu is consistent with internatal data. */
InteractMenu -> SubWindows[0].Str =
GlblTransformMode == TRANS_OBJECT ? "Object Coords." : "Screen Coords.";
InteractMenu -> SubWindows[1].Str =
GlblViewMode == VIEW_PERSPECTIVE ? "Perspective" : "Orthographic";
InteractMenu -> SubWindows[10].Str =
GlblDepthCue ? "Depth cue" : "No depth cue";
InteractMenu -> SubWindows[11].Str =
GlblDrawSolid ? "Solid" : "Wireframe";
winset(TransWinID); /* Draw in the transformation window. */
SubTransWidth = (int) (TransWinWidth * INTERACT_SUB_WINDOW_WIDTH);
SubTransHeight = (int) (TransWinHeight * INTERACT_SUB_WINDOW_HEIGHT);
SubTransPosX = (TransWinWidth - SubTransWidth) / 2;
GGMySetColor(BLACK);
clear();
for (i = 0; i < InteractNumOfSubWndws; i++) {
GGMySetColor(InteractMenu -> SubWindows[i].Color);
SubTransPosY = (int) (TransWinHeight * InteractMenu -> SubWindows[i].Y);
move2i(SubTransPosX, SubTransPosY);
draw2i(SubTransPosX + SubTransWidth, SubTransPosY);
draw2i(SubTransPosX + SubTransWidth, SubTransPosY + SubTransHeight);
draw2i(SubTransPosX, SubTransPosY + SubTransHeight);
draw2i(SubTransPosX, SubTransPosY);
if (InteractMenu -> SubWindows[i].TextInside) {
DrawText(InteractMenu -> SubWindows[i].Str,
TransWinWidth / 2,
SubTransPosY + SubTransHeight / 2);
}
else {
DrawText(InteractMenu -> SubWindows[i].Str,
(TransWinWidth - SubTransWidth) / 3,
SubTransPosY + SubTransHeight / 2);
move2i(SubTransPosX + SubTransWidth / 2, SubTransPosY);
draw2i(SubTransPosX + SubTransWidth / 2,
SubTransPosY + SubTransHeight);
}
}
for (i = 0; i < INTERACT_NUM_OF_STRINGS; i++) {
GGMySetColor(InteractMenu -> Strings[i].Color);
DrawText(InteractMenu -> Strings[i].Str,
(int) (InteractMenu -> Strings[i].X * TransWinWidth),
(int) (InteractMenu -> Strings[i].Y * TransWinHeight));
}
if (DoDoubleBuffer) swapbuffers();
winset(ViewWinID); /* Go back to the default drawing window. */
}
/*****************************************************************************
* Set up and draw a view window. *
*****************************************************************************/
static void SetViewWindow(void)
{
long PrefPos[4];
#ifndef _AIX
foreground();
#endif
if (sscanf(GlblViewPrefPos, "%ld, %ld, %ld, %ld",
&PrefPos[0], &PrefPos[1], &PrefPos[2], &PrefPos[3]) == 4)
prefposition(PrefPos[0], PrefPos[1], PrefPos[2], PrefPos[3]);
else if (sscanf(GlblViewPrefPos, "%ld, %ld",
&PrefPos[0], &PrefPos[1]) == 2)
prefsize(PrefPos[0], PrefPos[1]);
winopen("Poly3dView");
if (DoDoubleBuffer) doublebuffer();
RGBmode();
gconfig();
getorigin(&ViewWinLeft, &ViewWinLow);
getsize(&ViewWinWidth, &ViewWinHeight);
ViewWinWidth2 = ViewWinWidth / 2;
ViewWinHeight2 = ViewWinHeight / 2;
getmatrix(ViewStartMatrix);
ViewWinID = winget();
GGClearViewArea();
if (DoDoubleBuffer) swapbuffers();
concave(TRUE);
/* Define necessary staff for Lighting. */
lmdef(DEFMATERIAL, 1, 0, NULL);
lmdef(DEFLIGHT, 1, 0, NULL);
lmdef(DEFLMODEL, 1, 0, NULL);
/* This is wierd. without the sleep the gl get mixed up between the two */
/* windows. If you have any idea why, let me know... */
sleep(1);
}
/*****************************************************************************
* Return View window ID. *
*****************************************************************************/
long GetViewWindowID()
{
return ViewWinID;
}
/******************************************************************************
* Returns status of abort key if pressed, and reset it. *
******************************************************************************/
int GGIsAbortKeyPressed(void)
{
return getbutton(RIGHTMOUSE) == 1;
}
/******************************************************************************
* Handle gl events *
******************************************************************************/
GraphicEventType GGGetGraphicEvent(RealType *ChangeFactor)
{
static GraphicEventType
LastEvent = EVENT_NONE;
static long
LastX = -1;
int i,
LeftButtonIsPressed = getbutton(LEFTMOUSE) == 1;
GraphicEventType
RetVal = EVENT_NONE;
short data;
long x, y, dev;
RealType XPos, YPos;
if (!TransWindowDisplayed) {
/* Pop up the transformation window. */
SetTransformWindow();
RedrawTransformWindow();
TransWindowDisplayed = TRUE;
}
if (GlblWasCtrlBrk) {
GlblWasCtrlBrk = FALSE;
if (!PopTransWndwAlways) {
winclose(TransWinID);
TransWindowDisplayed = FALSE;
}
return EVENT_QUIT;
}
/* Allow continuous drag on following events only: */
if (LeftButtonIsPressed &&
!(LastEvent == EVENT_PERS_ORTHO_Z ||
LastEvent == EVENT_ROTATE_X ||
LastEvent == EVENT_ROTATE_Y ||
LastEvent == EVENT_ROTATE_Z ||
LastEvent == EVENT_TRANSLATE_X ||
LastEvent == EVENT_TRANSLATE_Y ||
LastEvent == EVENT_TRANSLATE_Z ||
LastEvent == EVENT_SCALE)) {
while (getbutton(LEFTMOUSE) == 1);
LeftButtonIsPressed = FALSE;
}
if (LeftButtonIsPressed) {
/* Allow leaving the Trans window if still pressed, and use last */
/* event as the returned event. Note we wait until current position */
/* is different from last one to make sure we do something. */
while((x = getvaluator(MOUSEX) - TransWinLeft) == LastX &&
getbutton(LEFTMOUSE) == 1);
if (x != LastX) {
*ChangeFactor = (((RealType) x) - LastX) / TransWinWidth2;
LastX = x;
return LastEvent;
}
else
LeftButtonIsPressed = FALSE;
}
LastEvent = EVENT_NONE;
while (RetVal == EVENT_NONE) {
/* Wait for left button to be pressed in the Trans window. Note this */
/* is the loop we are going to cycle in idle time. */
while (getbutton(LEFTMOUSE) != 1 ||
(x = getvaluator(MOUSEX)) < TransWinLeft ||
x > TransWinLeft + TransWinWidth ||
(y = getvaluator(MOUSEY)) < TransWinLow ||
y > TransWinLow + TransWinHeight) {
if (GlblWasCtrlBrk) {
GlblWasCtrlBrk = FALSE;
if (!PopTransWndwAlways) {
winclose(TransWinID);
TransWindowDisplayed = FALSE;
}
return EVENT_QUIT;
}
if (qtest()) { /* Any external event occured? */
switch (dev = qread(&data)) {
case REDRAW:
if (data == ViewWinID) {
getorigin(&ViewWinLeft, &ViewWinLow);
getsize(&ViewWinWidth, &ViewWinHeight);
ViewWinWidth2 = ViewWinWidth / 2;
ViewWinHeight2 = ViewWinHeight / 2;
reshapeviewport();
ortho2(-0.5, ViewWinWidth - 0.5,
-0.5, ViewWinHeight - 0.5);
getmatrix(ViewStartMatrix);
UpdateInteractHandleInput();
}
else if (data == TransWinID) {
winset(TransWinID);
getorigin(&TransWinLeft, &TransWinLow);
getsize(&TransWinWidth, &TransWinHeight);
reshapeviewport();
ortho2(-0.5, TransWinWidth - 0.5,
-0.5, TransWinHeight - 0.5);
TransWinWidth2 = TransWinWidth / 2;
RedrawTransformWindow();
winset(ViewWinID);
}
break;
}
}
}
x -= TransWinLeft;
y -= TransWinLow;
XPos = ((RealType) x) / TransWinWidth;
YPos = ((RealType) y) / TransWinHeight;
/* Make sure we are in bound in the X direction. */
if (XPos < (1.0 - INTERACT_SUB_WINDOW_WIDTH) / 2.0 ||
XPos > 1.0 - (1.0 - INTERACT_SUB_WINDOW_WIDTH) / 2.0) {
GGTone(1000, 100);
continue;
}
/* Now search the sub window the event occured in. */
for (i = 0; i < InteractNumOfSubWndws; i++) {
if (InteractMenu -> SubWindows[i].Y <= YPos &&
InteractMenu -> SubWindows[i].Y + INTERACT_SUB_WINDOW_HEIGHT >=
YPos) {
RetVal = InteractMenu -> SubWindows[i].Event;
break;
}
}
if (i == InteractNumOfSubWndws) {
GGTone(1000, 100);
continue;
}
/* Take care of special cases in which the window should be updated. */
switch (RetVal) {
case EVENT_SCR_OBJ_TGL:
GlblTransformMode = GlblTransformMode == TRANS_OBJECT ?
TRANS_SCREEN :
TRANS_OBJECT;
RedrawTransformWindow();
break;
case EVENT_PERS_ORTHO_TGL:
GlblViewMode = GlblViewMode == VIEW_PERSPECTIVE ?
VIEW_ORTHOGRAPHIC :
VIEW_PERSPECTIVE;
RedrawTransformWindow();
break;
case EVENT_DEPTH_CUE:
GlblDepthCue = !GlblDepthCue;
RedrawTransformWindow();
break;
case EVENT_DRAW_SOLID:
GlblDrawSolid = !GlblDrawSolid;
RedrawTransformWindow();
break;
case EVENT_QUIT:
if (!PopTransWndwAlways) {
winclose(TransWinID);
TransWindowDisplayed = FALSE;
}
break;
}
*ChangeFactor = (((RealType) x) - TransWinWidth2) / TransWinWidth2;
}
LastEvent = RetVal;
LastX = x;
return RetVal;
}
/******************************************************************************
* Flush output of graphic command. *
******************************************************************************/
void GGGraphicFlush(void)
{
/* We are using double buffering - flip buffers. */
if (DoDoubleBuffer) swapbuffers();
}
/******************************************************************************
* Draw text centered at the given position. *
******************************************************************************/
static void DrawText(char *Str, long PosX, long PosY)
{
long Width = strwidth(Str);
cmov2s(PosX - Width / 2, PosY - (getheight() / 2 - getdescender()));
charstr(Str);
}